home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / ip / nfs / nfswatch4.0 / nfslogsum.c < prev    next >
Encoding:
C/C++ Source or Header  |  1993-03-01  |  14.9 KB  |  824 lines

  1. #ifndef lint
  2. static char *RCSid = "$Header: /home/harbor/davy/system/nfswatch/RCS/nfslogsum.c,v 4.0 1993/03/01 19:59:00 davy Exp $";
  3. #endif
  4.  
  5. #include "os.h"
  6.  
  7. /*
  8.  * nfslogsum - summarize nfswatch log file
  9.  *
  10.  * David A. Curry                Jeffrey C. Mogul
  11.  * Purdue University                Digital Equipment Corporation
  12.  * Engineering Computer Network            Western Research Laboratory
  13.  * 1285 Electrical Engineering Building        250 University Avenue
  14.  * West Lafayette, IN 47907-1285        Palo Alto, CA 94301
  15.  * davy@ecn.purdue.edu                mogul@decwrl.dec.com
  16.  *
  17.  * $Log: nfslogsum.c,v $
  18.  * Revision 4.0  1993/03/01  19:59:00  davy
  19.  * NFSWATCH Version 4.0.
  20.  *
  21.  * Revision 3.4  1993/01/16  19:08:59  davy
  22.  * Corrected Jeff's address.
  23.  *
  24.  * Revision 3.3  1993/01/15  19:33:39  davy
  25.  * Miscellaneous cleanups.
  26.  *
  27.  * Revision 3.2  1993/01/14  03:41:21  davy
  28.  * Changed "Yellow Pages/NIS" to "YP/NIS/NIS+".
  29.  *
  30.  * Revision 3.1  1993/01/13  20:18:17  davy
  31.  * Put in OS-specific define scheme, and merged in Tim Hudson's code for
  32.  * SGI systems (as yet untested).
  33.  *
  34.  * Revision 3.0  1991/01/23  08:23:08  davy
  35.  * NFSWATCH Version 3.0.
  36.  *
  37.  * Revision 1.2  90/08/17  15:47:27  davy
  38.  * NFSWATCH Version 2.0.
  39.  * 
  40.  * Revision 1.1  88/11/29  11:20:38  davy
  41.  * NFSWATCH Release 1.0
  42.  * 
  43.  */
  44. #include <sys/param.h>
  45. #include <stdio.h>
  46.  
  47. #include "nfswatch.h"
  48.  
  49. char        *pname;                /* program name        */
  50. char        *logfile = LOGFILE;        /* log file name    */
  51.  
  52. int        logentries;            /* # of entries        */
  53. int        verbose = 0;            /* print more info    */
  54. int        maxlogentries = -1;        /* stop at this many    */
  55.  
  56. Counter        total_pkts;            /* total pkts this time    */
  57. Counter        tohost_pkts;            /* total pkts to host    */
  58. Counter        dropped_pkts;            /* total dropped pkts    */
  59.  
  60. char        *startdate;            /* time started        */
  61. char        *enddate;            /* time finished    */
  62.  
  63. char        srchost[MAXHOSTNAMELEN];    /* source host name    */
  64. char        dsthost[MAXHOSTNAMELEN];    /* destination host name*/
  65.  
  66. NFSCounter    nfs_counters[MAXEXPORT];    /* NFS pkt counters    */
  67. FileCounter    fil_counters[MAXEXPORT];    /* file pkt counters    */
  68. PacketCounter    pkt_counters[PKT_NCOUNTERS];    /* type pkt counters    */
  69.  
  70. char    *nfs_procs[] = {
  71.     "NULLPROC",    " GETATTR",    " SETATTR",    " GETROOT",
  72.     "  LOOKUP",    "READLINK",    "    READ",    "  WCACHE",
  73.     "   WRITE",    "  CREATE",    "  REMOVE",    "  RENAME",
  74.     "    LINK",    " SYMLINK",    "   MKDIR",    "   RMDIR",
  75.     " READDIR",    "  STATFS",    0
  76. };
  77.  
  78. char        *index();
  79. char        *savestr();
  80.  
  81. void        dumpit();
  82. void        dumpit2();
  83. void        parsenfs();
  84. void        parsetop();
  85. void        parsefile();
  86. void        parsepkts();
  87. void        parseproc();
  88. void        clearvars();
  89. void        parsetotals();
  90.  
  91. main(argc, argv)
  92. int argc;
  93. char **argv;
  94. {
  95.     FILE *logfp;
  96.     int printed = 0;
  97.     char line[BUFSIZ];
  98.  
  99.     pname = *argv;
  100.  
  101.     /*
  102.      * Process arguments.
  103.      */
  104.     while (--argc) {
  105.         if (**++argv != '-') {
  106.             logfile = *argv;
  107.             continue;
  108.         }
  109.  
  110.         switch (*++*argv) {
  111.         case 'v':
  112.             verbose++;
  113.             break;
  114.         default:
  115.             maxlogentries = atoi(*argv);
  116.             break;
  117.         }
  118.     }
  119.  
  120.     /*
  121.      * Open the log file.
  122.      */
  123.     if ((logfp = fopen(logfile, "r")) == NULL) {
  124.         (void) fprintf(stderr, "%s: cannot open \"%s\"\n", pname, logfile);
  125.         (void) exit(1);
  126.     }
  127.  
  128.     /*
  129.      * Read lines...
  130.      */
  131.     while (fgets(line, sizeof(line), logfp) != NULL) {
  132.         /*
  133.          * Skip blank comments.
  134.          */
  135.         if (!strcmp(line, "#\n"))
  136.             continue;
  137.  
  138.         /*
  139.          * Start of a new log session.
  140.          */
  141.         if (!strcmp(line, "# startlog\n")) {
  142.             clearvars();
  143.             printed = 0;
  144.             continue;
  145.         }
  146.  
  147.         /*
  148.          * Start of a new log entry.
  149.          */
  150.         if (!strcmp(line, "# begin\n")) {
  151.             parsetop(logfp);
  152.             continue;
  153.         }
  154.  
  155.         /*
  156.          * End of a log entry.
  157.          */
  158.         if (!strcmp(line, "# end\n")) {
  159.             logentries++;
  160.  
  161.             /*
  162.              * If we've read the max, we're done.
  163.              */
  164.             if ((maxlogentries > 0) &&
  165.                 (logentries >= maxlogentries)) {
  166.                 dumpit();
  167.                 exit(0);
  168.             }
  169.  
  170.             continue;
  171.         }
  172.  
  173.         /*
  174.          * End of log session.
  175.          */
  176.         if (!strcmp(line, "# endlog\n")) {
  177.             printed++;
  178.             dumpit();
  179.             continue;
  180.         }
  181.  
  182.         /*
  183.          * Start of NFS counter section.
  184.          */
  185.         if (!strncmp(line, "# nfs counters ", 15)) {
  186.             parsenfs(logfp);
  187.             continue;
  188.         }
  189.  
  190.         /*
  191.          * Start of file counter section.
  192.          */
  193.         if (!strncmp(line, "# file counters ", 16)) {
  194.             parsefile(logfp);
  195.             continue;
  196.         }
  197.  
  198.         /*
  199.          * Start of total packet section.
  200.          */
  201.         if (!strncmp(line, "# total packets ", 16)) {
  202.             parsetotals(logfp);
  203.             continue;
  204.         }
  205.  
  206.         /*
  207.          * Start of packet counter section.
  208.          */
  209.         if (!strncmp(line, "# packet counters ", 18)) {
  210.             parsepkts(logfp);
  211.             continue;
  212.         }
  213.  
  214.         /*
  215.          * Source host.
  216.          */
  217.         if (!strncmp(line, "#    Packets from: ", 19)) {
  218.             (void) strcpy(srchost, line + 19);
  219.             continue;
  220.         }
  221.  
  222.         /*
  223.          * Destination host.
  224.          */
  225.         if (!strncmp(line, "#    Packets to:   ", 19)) {
  226.             (void) strcpy(dsthost, line + 19);
  227.             continue;
  228.         }
  229.     }
  230.  
  231.     /*
  232.      * In case there's no endlog (logfile in progress).
  233.      */
  234.     if (!printed)
  235.         dumpit();
  236.  
  237.     (void) fclose(logfp);
  238.     (void) exit(0);
  239. }
  240.  
  241. /*
  242.  * clearvars - clear variables between log sessions.
  243.  */
  244. void
  245. clearvars()
  246. {
  247.     register int i;
  248.  
  249.     logentries = 0;
  250.     total_pkts = 0;
  251.     tohost_pkts = 0;
  252.     dropped_pkts = 0;
  253.  
  254.     if (startdate != NULL) {
  255.         (void) free(startdate);
  256.         startdate = NULL;
  257.     }
  258.  
  259.     if (enddate != NULL) {
  260.         (void) free(enddate);
  261.         enddate = NULL;
  262.     }
  263.  
  264.     (void) bzero((char *) pkt_counters,
  265.         PKT_NCOUNTERS * sizeof(PacketCounter));
  266.  
  267.     /*
  268.      * Set up the strings.
  269.      */
  270.     pkt_counters[PKT_NDREAD].pc_name = "ND Read";
  271.     pkt_counters[PKT_NDWRITE].pc_name = "ND Write";
  272.     pkt_counters[PKT_NFSREAD].pc_name = "NFS Read";
  273.     pkt_counters[PKT_NFSWRITE].pc_name = "NFS Write";
  274.     pkt_counters[PKT_NFSMOUNT].pc_name = "NFS Mount";
  275.     pkt_counters[PKT_YELLOWPAGES].pc_name = "YP/NIS/NIS+";
  276.     pkt_counters[PKT_RPCAUTH].pc_name = "RPC Authorization";
  277.     pkt_counters[PKT_OTHERRPC].pc_name = "Other RPC Packets";
  278.     pkt_counters[PKT_TCP].pc_name = "TCP Packets";
  279.     pkt_counters[PKT_UDP].pc_name = "UDP Packets";
  280.     pkt_counters[PKT_ICMP].pc_name = "ICMP Packets";
  281.     pkt_counters[PKT_ROUTING].pc_name = "Routing Control";
  282.     pkt_counters[PKT_ARP].pc_name = "Address Resolution";
  283.     pkt_counters[PKT_RARP].pc_name = "Reverse Addr Resol";
  284.     pkt_counters[PKT_BROADCAST].pc_name = "Ethernet Broadcast";
  285.     pkt_counters[PKT_OTHER].pc_name = "Other Packets";
  286.  
  287.     for (i = 0; i < MAXEXPORT; i++) {
  288.         if (nfs_counters[i].nc_name != NULL) {
  289.             (void) free(nfs_counters[i].nc_name);
  290.             nfs_counters[i].nc_name = NULL;
  291.         }
  292.     }
  293.  
  294.     (void) bzero((char *) nfs_counters,
  295.         MAXEXPORT * sizeof(NFSCounter));
  296.  
  297.     (void) bzero((char *) fil_counters,
  298.         MAXEXPORT * sizeof(FileCounter));
  299. }
  300.  
  301. /*
  302.  * parsetop - parse the top of the log session.
  303.  */
  304. void
  305. parsetop(fp)
  306. FILE *fp;
  307. {
  308.     int nskip = 0;
  309.     char line[BUFSIZ];
  310.  
  311.     /*
  312.      * Get lines...
  313.      */
  314.     while (fgets(line, sizeof(line), fp) != NULL) {
  315.         /*
  316.          * Second blank comment terminates this section.
  317.          */
  318.         if (!strcmp(line, "#\n")) {
  319.             if (++nskip == 2)
  320.                 return;
  321.  
  322.             continue;
  323.         }
  324.  
  325.         /*
  326.          * Grab the date - first one is start,
  327.          * otherwise end.
  328.          */
  329.         if (!strncmp(line, "Date: ", 6)) {
  330.             if (startdate == NULL) {
  331.                 startdate = savestr(line + 6);
  332.                 enddate = savestr(line + 6);
  333.             }
  334.             else {
  335.                 (void) strcpy(enddate, line + 6);
  336.             }
  337.  
  338.             continue;
  339.         }
  340.     }
  341. }
  342.  
  343. /*
  344.  * parsetotals - parse the totals section.
  345.  */
  346. void
  347. parsetotals(fp)
  348. FILE *fp;
  349. {
  350.     int x, y, z;
  351.     int nskip = 0;
  352.     register char *s;
  353.     char line[BUFSIZ];
  354.  
  355.     /*
  356.      * Get lines...
  357.      */
  358.     while (fgets(line, sizeof(line), fp) != NULL) {
  359.         /*
  360.          * Seond blank comment terminates this section.
  361.          */
  362.         if (!strcmp(line, "#\n")) {
  363.             if (++nskip == 2)
  364.                 return;
  365.  
  366.             continue;
  367.         }
  368.  
  369.         /*
  370.          * Grab the interval packets and add them.
  371.          */
  372.         if (!strncmp(line, "Interval Packets:", 17)) {
  373.             (void) sscanf(line + 17, "%d %d %d", &x, &y, &z);
  374.  
  375.             total_pkts += x;
  376.             tohost_pkts += y;
  377.             dropped_pkts += z;
  378.  
  379.             continue;
  380.         }
  381.     }
  382. }
  383.  
  384. /*
  385.  * parsepkts - parse packet counter section.
  386.  */
  387. void
  388. parsepkts(fp)
  389. FILE *fp;
  390. {
  391.     int x, y, z;
  392.     int nskip = 0;
  393.     register int i;
  394.     register char *s;
  395.     char line[BUFSIZ];
  396.  
  397.     /*
  398.      * Get lines...
  399.      */
  400.     while (fgets(line, sizeof(line), fp) != NULL) {
  401.         /*
  402.          * Second blank comment terminates this section.
  403.          */
  404.         if (!strcmp(line, "#\n")) {
  405.             if (++nskip == 2)
  406.                 return;
  407.  
  408.             continue;
  409.         }
  410.  
  411.         /*
  412.          * Find the numbers.
  413.          */
  414.         if ((s = index(line, ':')) == NULL)
  415.             continue;
  416.  
  417.         *s++ = NULL;
  418.  
  419.         /*
  420.          * Find the type we need.
  421.          */
  422.         for (i = 0; i < PKT_NCOUNTERS; i++) {
  423.             if (!strcmp(line, pkt_counters[i].pc_name)) {
  424.                 (void) sscanf(s, "%d %d%% %d", &x, &y, &z);
  425.  
  426.                 pkt_counters[i].pc_total += x;
  427.                 break;
  428.             }
  429.         }
  430.     }
  431. }
  432.  
  433. /*
  434.  * parsenfs - parse the NFS counter section.
  435.  */
  436. void
  437. parsenfs(fp)
  438. FILE *fp;
  439. {
  440.     int x, y, z;
  441.     int nskip = 0;
  442.     register int i;
  443.     register char *s;
  444.     char line[BUFSIZ];
  445.  
  446.     /*
  447.      * Get lines...
  448.      */
  449.     while (fgets(line, sizeof(line), fp) != NULL) {
  450.         /*
  451.          * Second blank comment terminates this section.
  452.          */
  453.         if (!strcmp(line, "#\n")) {
  454.             if (++nskip == 2)
  455.                 return;
  456.  
  457.             continue;
  458.         }
  459.  
  460.         /*
  461.          * Find the numbers.
  462.          */
  463.         if ((s = index(line, ':')) == NULL)
  464.             continue;
  465.  
  466.         *s++ = NULL;
  467.  
  468.         /*
  469.          * Find the NFS counter we want.
  470.          */
  471.         if ((i = findnfs(line)) < 0)
  472.             continue;
  473.  
  474.         (void) sscanf(s, "%d %d%% %d", &x, &y, &z);
  475.         nfs_counters[i].nc_total += x;
  476.  
  477.         if ((s = index(s, '(')) != NULL)
  478.             parseproc(s, nfs_counters[i].nc_proc);
  479.     }
  480. }
  481.  
  482. /*
  483.  * parsefile - parse the file counter section.
  484.  */
  485. void
  486. parsefile(fp)
  487. FILE *fp;
  488. {
  489.     int x, y, z;
  490.     int nskip = 0;
  491.     register int i;
  492.     register char *s;
  493.     char line[BUFSIZ];
  494.  
  495.     /*
  496.      * Get lines...
  497.      */
  498.     while (fgets(line, sizeof(line), fp) != NULL) {
  499.         /*
  500.          * Second blank comment terminates this section.
  501.          */
  502.         if (!strcmp(line, "#\n")) {
  503.             if (++nskip == 2)
  504.                 return;
  505.  
  506.             continue;
  507.         }
  508.  
  509.         /*
  510.          * Find the numbers.
  511.          */
  512.         if ((s = index(line, ':')) == NULL)
  513.             continue;
  514.  
  515.         *s++ = NULL;
  516.  
  517.         /*
  518.          * Find the file counter we want.
  519.          */
  520.         if ((i = findfile(line)) < 0)
  521.             continue;
  522.  
  523.         (void) sscanf(s, "%d %d%% %d", &x, &y, &z);
  524.         fil_counters[i].fc_total += x;
  525.  
  526.         if ((s = index(s, '(')) != NULL)
  527.             parseproc(s, fil_counters[i].fc_proc);
  528.     }
  529. }
  530.  
  531. /*
  532.  * parseproc - parse the NFS procedure counters.
  533.  */
  534. void
  535. parseproc(line, ctrs)
  536. Counter *ctrs;
  537. char *line;
  538. {
  539.     register int i;
  540.     register char *s;
  541.  
  542.     s = line + 1;
  543.  
  544.     for (i = 0; i < MAXNFSPROC; i++) {
  545.         ctrs[i] += atoi(s);
  546.  
  547.         if ((s = index(s, '/')) == NULL)
  548.             return;
  549.  
  550.         s++;
  551.     }
  552. }
  553.  
  554. /*
  555.  * dumpit - print out the information.
  556.  */
  557. void
  558. dumpit()
  559. {
  560.     float percent;
  561.     char buf[BUFSIZ];
  562.     register int i, nfstotal;
  563.  
  564.     (void) printf("NFSwatch logfile summary:\n");
  565.     (void) printf("    Log time:     %.24s to %.24s\n", startdate, enddate);
  566.     (void) printf("    Log entries:  %d\n", logentries);
  567.     (void) printf("    Packets from: %s", srchost);
  568.     (void) printf("    Packets to:   %s\n", dsthost);
  569.  
  570.     (void) printf("Total packets:\n");
  571.     (void) printf("    %8d (network) %8d (to host) %8d (dropped)\n\n",
  572.         total_pkts, tohost_pkts, dropped_pkts);
  573.  
  574.     (void) printf("Packet counters:\n");
  575.  
  576.     /*
  577.      * Print the packet counters.  Percentage is calculated as
  578.      * this counter over total packets.
  579.      */
  580.     for (i = 0; i < PKT_NCOUNTERS; i++) {
  581.         if (total_pkts) {
  582.             percent = ((float) pkt_counters[i].pc_total /
  583.                   (float) tohost_pkts) * 100.0;
  584.         }
  585.         else {
  586.             percent = 0.0;
  587.         }
  588.  
  589.         (void) sprintf(buf, "%s:", pkt_counters[i].pc_name);
  590.         (void) printf("    %-25s %8d %7.0f%%\n",
  591.             buf, pkt_counters[i].pc_total, percent);
  592.  
  593.         if (i == (PKT_NCOUNTERS/2 - 1))
  594.             (void) putchar('\n');
  595.     }
  596.  
  597.     /*
  598.      * Calculate the total number of NFS packets.
  599.      */
  600.     nfstotal = pkt_counters[PKT_NFSWRITE].pc_total +
  601.            pkt_counters[PKT_NFSREAD].pc_total;
  602.  
  603.     if (nfs_counters[0].nc_name != NULL)
  604.         (void) printf("\nNFS counters:\n");
  605.  
  606.     /*
  607.      * Print the NFS counters.  Percentage is calculated as
  608.      * packets this file system over total NFS packets.
  609.      */
  610.     for (i = 0; i < MAXEXPORT; i++) {
  611.         if (nfs_counters[i].nc_name == NULL)
  612.             continue;
  613.  
  614.         if (nfstotal) {
  615.             percent = ((float) nfs_counters[i].nc_total /
  616.                   (float) nfstotal) * 100.0;
  617.         }
  618.         else {
  619.             percent = 0.0;
  620.         }
  621.  
  622.         (void) sprintf(buf, "%s:", nfs_counters[i].nc_name);
  623.         (void) printf("    %-25s %8d %7.0f%%\n",
  624.             buf, nfs_counters[i].nc_total, percent);
  625.     }
  626.  
  627.     if (fil_counters[0].fc_name != NULL)
  628.         (void) printf("\nFile counters:\n");
  629.  
  630.     /*
  631.      * Print the file counters.  Percentage is calculated as
  632.      * packets this file over total NFS packets.
  633.      */
  634.     for (i = 0; i < MAXEXPORT; i++) {
  635.         if (fil_counters[i].fc_name == NULL)
  636.             continue;
  637.  
  638.         if (nfstotal) {
  639.             percent = ((float) fil_counters[i].fc_total /
  640.                   (float) nfstotal) * 100.0;
  641.         }
  642.         else {
  643.             percent = 0.0;
  644.         }
  645.  
  646.         (void) sprintf(buf, "%s:", fil_counters[i].fc_name);
  647.         (void) printf("    %-25s %8d %7.0f%%\n",
  648.             buf, fil_counters[i].fc_total, percent);
  649.     }
  650.  
  651.     (void) putchar('\014');
  652.  
  653.     /*
  654.      * If needed, put out the extra info.
  655.      */
  656.     if (verbose)
  657.         dumpit2();
  658. }
  659.  
  660. /*
  661.  * dumpit2 - dump even more information.
  662.  */
  663. void
  664. dumpit2()
  665. {
  666.     register int i, j, k;
  667.     
  668.     /*
  669.      * Print NFS procs in groups of 6.
  670.      */
  671.     for (i = 0; i < MAXNFSPROC; i += 6) {
  672.         /*
  673.          * Print header.
  674.          */
  675.         (void) printf("NFSwatch logfile summary:\n");
  676.         (void) printf("    Log time:     %.24s to %.24s\n",
  677.             startdate, enddate);
  678.         (void) printf("    Log entries:  %d\n", logentries);
  679.         (void) printf("    Packets from: %s", srchost);
  680.         (void) printf("    Packets to:   %s\n", dsthost);
  681.         (void) printf("NFS Procedure Call Summary (part %d):\n",
  682.             ((i / 6) + 1));
  683.         (void) printf("                         ");
  684.  
  685.         for (j = 0; j < 6; j++)
  686.             (void) printf("%s ", nfs_procs[i+j]);
  687.  
  688.         (void) putchar('\n');
  689.  
  690.         /*
  691.          * Print NFS counters.
  692.          */
  693.         for (j = 0; j < MAXEXPORT; j++) {
  694.             if (nfs_counters[j].nc_name == NULL)
  695.                 continue;
  696.  
  697.             (void) printf("%-25s", nfs_counters[j].nc_name);
  698.  
  699.             for (k = 0; k < 6; k++) {
  700.                 (void) printf("%8d ",
  701.                     nfs_counters[j].nc_proc[i+k]);
  702.             }
  703.  
  704.             (void) putchar('\n');
  705.         }
  706.  
  707.         if (fil_counters[0].fc_name != NULL)
  708.             (void) putchar('\n');
  709.  
  710.         /*
  711.          * Print file counters.
  712.          */
  713.         for (j = 0; j < MAXEXPORT; j++) {
  714.             if (fil_counters[j].fc_name == NULL)
  715.                 continue;
  716.  
  717.             (void) printf("%-25s", fil_counters[j].fc_name);
  718.  
  719.             for (k = 0; k < 6; k++) {
  720.                 (void) printf("%8d ",
  721.                     fil_counters[j].fc_proc[i+k]);
  722.             }
  723.  
  724.             (void) putchar('\n');
  725.         }
  726.  
  727.         (void) putchar('\014');
  728.     }
  729. }
  730.  
  731. /*
  732.  * findnfs - find the counter associated with name.
  733.  */
  734. int
  735. findnfs(name)
  736. char *name;
  737. {
  738.     register int i;
  739.  
  740.     /*
  741.      * Look for it.
  742.      */
  743.     for (i = 0; i < MAXEXPORT; i++) {
  744.         /*
  745.          * At end of list.
  746.          */
  747.         if (nfs_counters[i].nc_name == NULL)
  748.             break;
  749.  
  750.         /*
  751.          * Found it.
  752.          */
  753.         if (!strcmp(name, nfs_counters[i].nc_name))
  754.             return(i);
  755.     }
  756.  
  757.     /*
  758.      * If there's room, add it to the list.
  759.      */
  760.     if (i < MAXEXPORT) {
  761.         nfs_counters[i].nc_name = savestr(name);
  762.         return(i);
  763.     }
  764.  
  765.     return(-1);
  766. }
  767.  
  768. /*
  769.  * findfile - find the counter assopciated with name.
  770.  */
  771. int
  772. findfile(name)
  773. char *name;
  774. {
  775.     register int i;
  776.  
  777.     /*
  778.      * Look for it.
  779.      */
  780.     for (i = 0; i < MAXEXPORT; i++) {
  781.         /*
  782.          * At end of list.
  783.          */
  784.         if (fil_counters[i].fc_name == NULL)
  785.             break;
  786.  
  787.         /*
  788.          * Found it.
  789.          */
  790.         if (!strcmp(name, fil_counters[i].fc_name))
  791.             return(i);
  792.     }
  793.  
  794.     /*
  795.      * If there's room, add it to the list.
  796.      */
  797.     if (i < MAXEXPORT) {
  798.         fil_counters[i].fc_name = savestr(name);
  799.         return(i);
  800.     }
  801.  
  802.     return(-1);
  803. }
  804.  
  805. /*
  806.  * savestr - save string in dynamic memory.
  807.  */
  808. char *
  809. savestr(s)
  810. char *s;
  811. {
  812.     char *t;
  813.     char *malloc();
  814.  
  815.     if ((t = malloc(strlen(s) + 1)) == NULL) {
  816.         (void) fprintf(stderr, "%s: out of memory.\n", pname);
  817.         (void) exit(1);
  818.     }
  819.  
  820.     (void) strcpy(t, s);
  821.  
  822.     return(t);
  823. }
  824.